﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using ESRI.ArcGIS.Client.Geometry;

using Microsoft.Surface;
using Microsoft.Surface.Presentation;
using Microsoft.Surface.Presentation.Controls;
using Microsoft.Surface.Presentation.Input;


namespace GISforTT_API
{
    /// <summary>
    /// Interaction logic for BookmarkListFrame.xaml.  This
    /// is a ScatterViewItem that contains a list of Bookmarks.
    /// </summary>
    public partial class BookmarkListFrame : ScatterViewItem
    {
        public ItemCollection BookmarkListItems
        {
            get
            {
                return BookmarkListBox.Items;
            }
        }

        /// <summary>
 
        /// Creates a BookmarkListFrame.  It takes a reference of 
        /// the ScatterLayer (where the frame itself exists),
        /// a Point (where the frame should appear in the ScatterView),
        /// and the orientation of the frame itself.
        /// </summary>
        /// <param name="pt">a Point (where the frame should appear in the ScatterView)</param>
        /// <param name="orientation">the orientation of the frame</param>
        public BookmarkListFrame(Point pt, double orientation)
        {
            InitializeComponent();

            this.Center = pt;
            this.Orientation = orientation;

            PopulateBookmarkList();
        }

        



        /// <summary>
        /// 
        /// Populates the list frame with
        /// bookmarks from the BookmarkList singleton.
        /// </summary>
        public void PopulateBookmarkList()
        {
            foreach (Bookmark tt in BookmarkList.Instance.getBookmarks())
            {
                this.AddBookmark(tt);
            }
        }

        /// <summary>
        /// Adds a Bookmark item to the BookmarkList
        /// </summary>
        /// <param name="inputBookmark">Bookmark to be added</param>
        public BookmarkListItem AddBookmark(Bookmark inputBookmark)
        {
            BookmarkListItem inputItem = new BookmarkListItem(inputBookmark);
            BookmarkListBox.Items.Add(inputItem);

            inputItem.Selected += new RoutedEventHandler(BookmarkListItem_Selected);

            return inputItem;
        }

        
        /// <summary>
        /// Removes a Bookmark from the BookmarkList
        /// </summary>
        /// <param name="deleteItem">The BookmarkListItem to be deleted</param>
        public void RemoveBookmarkItem(BookmarkListItem deleteItem)
        {
            if (BookmarkListBox.Items.Contains(deleteItem))
                BookmarkListBox.Items.Remove(deleteItem);
        }

        /// <summary>
        /// Event handler when an item (Bookmark) is tapped in the
        /// BookmarkList.  When this happens, a MapFrame representing
        /// the tapped Bookmark appears.  We also calculate where this
        /// MapFrame should appear.  The MapFrame should be close to the
        /// BookmarkList.
        /// This was originally the contact tap handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>        
        private void BookmarkListItem_Selected(object sender, RoutedEventArgs e)
        {

            BookmarkListItem touchedBookmarkItem = sender as BookmarkListItem;
            Bookmark touchedBookmark = touchedBookmarkItem.Bookmark;
            Point centrePoint = this.Center;

            /* Calculate where the map frame should go */

            /* by default, the map frame would appear in the centre of the screen */
            Point result = new Point(384, 512);
            Point leftPt = new Point(0, 0);
            Point topPt = new Point(0, 0);
            Point rightPt = new Point(0, 0);
            Point btmPt = new Point(0, 0);

            /* The position of the map frame depends on the orientation
             * of the Bookmark list itself
             */
            if (this.Orientation >= 270 && this.Orientation < 360)
            {
                double radian = Math.PI * (Math.Abs(this.Orientation - 360)) / 180.0;
                double y = Math.Sin(radian) * ( 20 + touchedBookmark.MapFrameWidth);
                double x = Math.Cos(radian) * ( 20 + touchedBookmark.MapFrameWidth);
                leftPt = new Point(this.Center.X - x, this.Center.Y + y);
                result = leftPt;

                if (OutOfBounds(leftPt))
                {
                    x = Math.Sin(radian) * (20 + touchedBookmark.MapFrameHeight);
                    y = Math.Cos(radian) * (20 + touchedBookmark.MapFrameHeight);
                    topPt = new Point(this.Center.X - x, this.Center.Y - y);
                    result = topPt;
                    
                    if (OutOfBounds(topPt))
                    {
                        y = Math.Sin(radian) * (20 + touchedBookmark.MapFrameWidth);
                        x = Math.Cos(radian) * (20 + touchedBookmark.MapFrameWidth);
                        rightPt = new Point(this.Center.X + x, this.Center.Y - y);
                        result = rightPt;

                        if (OutOfBounds(rightPt))
                        {
                            x = Math.Sin(radian) * (20 + touchedBookmark.MapFrameHeight);
                            y = Math.Cos(radian) * (20 + touchedBookmark.MapFrameHeight);
                            btmPt = new Point(this.Center.X + x, this.Center.Y + y);
                            result = btmPt;
                        }
                    }
                }

            }
            if (this.Orientation >= 0 && this.Orientation < 90)
            {
                double radian = Math.PI * this.Orientation / 180.0;
                double y = Math.Sin(radian) * (20 + touchedBookmark.MapFrameWidth);
                double x = Math.Cos(radian) * (20 + touchedBookmark.MapFrameWidth);
                leftPt = new Point(this.Center.X - x, this.Center.Y - y);
                result = leftPt;

                if (OutOfBounds(leftPt))
                {
                    x = Math.Sin(radian) * (touchedBookmark.MapFrameHeight);
                    y = Math.Cos(radian) * (touchedBookmark.MapFrameHeight);
                    topPt = new Point(this.Center.X + x, this.Center.Y - y);
                    result = topPt;
                    if (OutOfBounds(topPt))
                    {
                        y = Math.Sin(radian) * (20 + touchedBookmark.MapFrameWidth);
                        x = Math.Cos(radian) * (20 + touchedBookmark.MapFrameWidth);
                        rightPt = new Point(this.Center.X + x, this.Center.Y + y);
                        result = rightPt;

                        if (OutOfBounds(rightPt))
                        {
                            x = Math.Sin(radian) * (touchedBookmark.MapFrameHeight);
                            y = Math.Cos(radian) * (touchedBookmark.MapFrameHeight);
                            btmPt = new Point(this.Center.X - x, this.Center.Y + y);
                            result = btmPt;
                        }
                    }
                }
                
            }
            if (this.Orientation >= 90 && this.Orientation < 180)
            {
                double radian = Math.PI * (Math.Abs(this.Orientation - 180)) / 180.0;
                double y = Math.Sin(radian) * (20 + touchedBookmark.MapFrameWidth);
                double x = Math.Cos(radian) * (20 + touchedBookmark.MapFrameWidth);
                leftPt = new Point(this.Center.X + x, this.Center.Y - y);
                result = leftPt;

                if (OutOfBounds(leftPt))
                {
                    x = Math.Sin(radian) * (touchedBookmark.MapFrameHeight);
                    y = Math.Cos(radian) * (touchedBookmark.MapFrameHeight);
                    topPt = new Point(this.Center.X + x, this.Center.Y + y);
                    result = topPt;
                    if (OutOfBounds(topPt))
                    {
                        y = Math.Sin(radian) * (20 + touchedBookmark.MapFrameWidth);
                        x = Math.Cos(radian) * (20 + touchedBookmark.MapFrameWidth);
                        rightPt = new Point(this.Center.X - x, this.Center.Y + y);
                        result = rightPt;

                        if (OutOfBounds(rightPt))
                        {
                            x = Math.Sin(radian) * (touchedBookmark.MapFrameHeight);
                            y = Math.Cos(radian) * (touchedBookmark.MapFrameHeight);
                            btmPt = new Point(this.Center.X - x, this.Center.Y - y);
                            result = btmPt;
                        }
                    }
                }
            }
            if (this.Orientation >= 180 && this.Orientation < 270)
            {
                double radian = Math.PI * (Math.Abs(this.Orientation - 360)) / 180.0;
                double y = Math.Sin(radian) * (20 + touchedBookmark.MapFrameWidth);
                double x = Math.Abs(Math.Cos(radian) * (20 + touchedBookmark.MapFrameWidth));
                leftPt = new Point(this.Center.X - x, this.Center.Y + y);
                result = leftPt;

                if (OutOfBounds(leftPt))
                {
                    x = Math.Sin(radian) * (touchedBookmark.MapFrameHeight);
                    y = Math.Abs(Math.Cos(radian) * (touchedBookmark.MapFrameHeight));
                    topPt = new Point(this.Center.X - x, this.Center.Y + y);
                    result = topPt;
                    if (OutOfBounds(topPt))
                    {
                        y = Math.Sin(radian) * (20 + touchedBookmark.MapFrameWidth);
                        x = Math.Abs(Math.Cos(radian) * (20 + touchedBookmark.MapFrameWidth));
                        rightPt = new Point(this.Center.X - x, this.Center.Y - y);
                        result = rightPt;

                        if (OutOfBounds(rightPt))
                        {
                            x = Math.Sin(radian) * (touchedBookmark.MapFrameHeight);
                            y = Math.Abs(Math.Cos(radian) * (touchedBookmark.MapFrameHeight));
                            btmPt = new Point(this.Center.X + x, this.Center.Y - y);
                            result = btmPt;
                        }
                    }
                }
            }

            MapFrame mf = MapFrameFactory.Instance.CreateMapFrame(touchedBookmark, result, this.Orientation - 90, true /*from a Bookmark list*/);
            
            BackgroundMapLayer.Instance.AddMapFrame(mf);
            
        }



        /// <summary>
        /// Determines if a point is outside the
        /// acceptable bounds of the screen.
        /// </summary>
        /// <param name="pt"></param>
        /// <returns></returns>
        private bool OutOfBounds(Point pt)
        {
            return pt.X < 200 || pt.X > 600|| pt.Y < 200 || pt.Y > 800;
        }

        private void Close_Button_Click(object sender, RoutedEventArgs e)
        {
            BackgroundMapLayer.Instance.RemoveBookmarkListFrame(this);
        }







    }
}
